// import com.alibaba.druid.sql.ast.expr.*;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
// import com.alibaba.druid.sql.visitor.functions.Function;

// import java.util.ArrayList;
// import java.util.HashMap;
// import java.util.List;
// import java.util.Map;

#include "MySqlEvalVisitorImpl.h"
#include "../../../visitor/SQLEvalVisitorUtils.h"
#include "../../../ast/expr/SQLIntegerExpr.h"
#include "../../../ast/expr/SQLBooleanExpr.h"
#include "../../../ast/expr/SQLNumericLiteralExpr.h"
#include "../../../ast/expr/SQLNumberExpr.h"

MySqlEvalVisitorImpl::MySqlEvalVisitorImpl()
    : MySqlEvalVisitorImpl(std::make_shared<std::list<Object_ptr>>())
{
}

MySqlEvalVisitorImpl::MySqlEvalVisitorImpl(Object_list_ptr parameters)
{
  this->parameters = parameters;
  this->variantIndex = -1;
  this->markVariantIndex = true;
}

Object_list_ptr MySqlEvalVisitorImpl::getParameters()
{
  return parameters;
}

void MySqlEvalVisitorImpl::setParameters(Object_list_ptr parameters)
{
  this->parameters = parameters;
}

bool MySqlEvalVisitorImpl::visit(SQLCharExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

int MySqlEvalVisitorImpl::incrementAndGetVariantIndex()
{
  return ++variantIndex;
}

int MySqlEvalVisitorImpl::getVariantIndex()
{
  return variantIndex;
}

bool MySqlEvalVisitorImpl::visit(SQLVariantRefExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

bool MySqlEvalVisitorImpl::visit(SQLBinaryOpExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

bool MySqlEvalVisitorImpl::visit(SQLUnaryExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

bool MySqlEvalVisitorImpl::visit(SQLIntegerExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, std::dynamic_pointer_cast<SQLNumericLiteralExpr>(x));
}

bool MySqlEvalVisitorImpl::visit(SQLNumberExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, std::dynamic_pointer_cast<SQLNumericLiteralExpr>(x));
}

bool MySqlEvalVisitorImpl::visit(SQLHexExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLBinaryExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLCaseExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLBetweenExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLInListExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLNullExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLMethodInvokeExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLQueryExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

bool MySqlEvalVisitorImpl::isMarkVariantIndex()
{
  return markVariantIndex;
}

void MySqlEvalVisitorImpl::setMarkVariantIndex(bool markVariantIndex)
{
  this->markVariantIndex = markVariantIndex;
}

// @Override
SQLFunction* MySqlEvalVisitorImpl::getFunction(std::string funcName)
{
  auto it = functions.find(funcName);
  if (it != functions.end())
  {
    return it->second;
  }
  else
  {
    return nullptr;
  }
}

// @Override
void MySqlEvalVisitorImpl::registerFunction(std::string funcName, SQLFunction* function)
{
  functions.insert(std::make_pair(funcName, function));
}

bool MySqlEvalVisitorImpl::visit(SQLIdentifierExpr_ptr x)
{
  return SQLEvalVisitorUtils::visit(this, x);
}

// @Override
void MySqlEvalVisitorImpl::unregisterFunction(std::string funcName)
{
  functions.erase(funcName);
}

// @Override
bool MySqlEvalVisitorImpl::visit(SQLBooleanExpr_ptr x)
{
  Object_ptr value = Object_ptr(new Object(x->getBooleanValue()));
  x->getAttributes()->insert(std::make_pair(SQLEvalVisitor::EVAL_VALUE->c_str(), value));
  return false;
}
